package edu.ynu.se.xiecheng.achitectureclass.digitalagriculture.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import edu.ynu.se.xiecheng.achitectureclass.digitalagriculture.component.MonitorComponent;
import edu.ynu.se.xiecheng.achitectureclass.digitalagriculture.component.SoilComponent;
import edu.ynu.se.xiecheng.achitectureclass.digitalagriculture.entity.DeviceEntity;
import edu.ynu.se.xiecheng.achitectureclass.digitalagriculture.entity.DeviceMonitorRecordEntity;
import edu.ynu.se.xiecheng.achitectureclass.digitalagriculture.entity.DeviceSoilRecordEntity;
import edu.ynu.se.xiecheng.achitectureclass.digitalagriculture.entity.GreenhouseEntity;
import edu.ynu.se.xiecheng.achitectureclass.digitalagriculture.service.DeviceMonitorRecordService;
import edu.ynu.se.xiecheng.achitectureclass.digitalagriculture.service.DeviceService;
import edu.ynu.se.xiecheng.achitectureclass.digitalagriculture.service.DeviceSoilRecordService;
import edu.ynu.se.xiecheng.achitectureclass.digitalagriculture.service.GreenhouseService;
import edu.ynu.se.xiecheng.achitectureclass.digitalagriculture.utils.PageUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;

/**
 * 设备控制器
 * 设计原则体现：
 * 1. MVC架构模式 - 作为Controller层处理请求和响应
 * 2. 依赖注入(DI)原则 - 通过@Resource注入所需服务
 */
@RestController
@RequestMapping("/device")
public class DeviceController {

    // 依赖注入原则 - 面向接口编程，不直接实例化依赖
    @Resource
    private DeviceService deviceService;
    @Resource
    private GreenhouseService greenhouseService;
    @Resource
    private DeviceSoilRecordService deviceSoilRecordService;
    @Resource
    private DeviceMonitorRecordService deviceMonitorRecordService;

    // 通过配置注入而非硬编码
    @Value("${interfaceConfig.soilToken}")
    private String soilToken;
    @Value("${interfaceConfig.monitorToken}")
    private String monitorToken;

    /**
     * 加载监控数据
     * 设计原则体现：
     * 1. 单一职责原则 - 方法只负责加载监控数据
     * 2. 分层架构 - Controller调用Service层处理业务逻辑
     */
    @RequestMapping("/loadMonitorData")
    public String loadMonitorData(Long boxId) {

        GreenhouseEntity greenhouseEntity = greenhouseService.getById(boxId);

        if (greenhouseEntity == null) {
            return "notExist";
        }

        List<DeviceEntity> deviceEntityList = deviceService.getDeviceByBoxId(boxId, "monitor");

        if (deviceEntityList.isEmpty()) {
            return "notData";
        }

        List<DeviceMonitorRecordEntity> deviceMonitorRecordEntityList = Lists.newArrayList();

        for (DeviceEntity deviceEntity : deviceEntityList
        ) {
            String imagesUrl = MonitorComponent.getImagesUrl(monitorToken, deviceEntity.getSn());

            if (imagesUrl != null) {

                DeviceMonitorRecordEntity deviceMonitorRecordEntity = new DeviceMonitorRecordEntity();

                deviceMonitorRecordEntity.setDeviceId(deviceEntity.getId());
                deviceMonitorRecordEntity.setImagesUrl(imagesUrl);

                deviceMonitorRecordEntityList.add(deviceMonitorRecordEntity);
            }
        }

        deviceMonitorRecordService.saveBatch(deviceMonitorRecordEntityList);
        return "success";
    }

    /**
     * 加载土壤数据
     * 设计原则体现：
     * 1. 关注点分离 - 数据加载和业务处理分离
     * 2. 异常处理 - 统一的异常处理机制
     */
    @RequestMapping("/loadSoilData")
    public String loadSoilData(Long boxId) {

        GreenhouseEntity greenhouseEntity = greenhouseService.getById(boxId);

        if (greenhouseEntity == null) {
            return "notExist";
        }

        List<DeviceEntity> deviceEntityList = deviceService.getDeviceByBoxId(boxId, "soil");

        if (deviceEntityList.isEmpty()) {
            return "notData";
        }

        try {
            JSONArray jsonArray = SoilComponent.getData(deviceEntityList, greenhouseEntity.getBoxNo(), soilToken);

            if (jsonArray.isEmpty()){
                return "tokenError";
            }

            List<DeviceSoilRecordEntity> deviceSoilRecordEntities = Lists.newArrayList();
            for (int i = 0; i < jsonArray.size(); i++
            ) {
                JSONObject dataJson = jsonArray.getJSONObject(i);
                System.out.println(dataJson);
                DeviceEntity deviceEntity = deviceService.getDeviceBySn(dataJson.getString("id"));

                if (deviceEntity == null) {
                    continue;
                }
                DeviceSoilRecordEntity deviceSoilRecordEntity = new DeviceSoilRecordEntity();

                deviceSoilRecordEntity.setDeviceId(deviceEntity.getId());
                deviceSoilRecordEntity.setName(dataJson.getString("name"));
                deviceSoilRecordEntity.setValue(dataJson.getString("value"));
                deviceSoilRecordEntity.setTime(dataJson.getDate("timestamp"));
                deviceSoilRecordEntities.add(deviceSoilRecordEntity);
            }

            deviceSoilRecordService.saveBatch(deviceSoilRecordEntities);
        } catch (Exception e) {
            e.printStackTrace();
            return "getDataError";
        }
        return "success";
    }

    /**
     * 删除
     *
     * @param id
     * @return
     */
    @RequestMapping("/delete")
    public String delete(Long id) {
        deviceService.removeById(id);
        return "success";
    }

    /**
     * 保存
     *
     * @param deviceEntity
     * @return
     */
    @RequestMapping("/save")
    public String save(DeviceEntity deviceEntity) {
        deviceService.save(deviceEntity);
        return "success";
    }

    /**
     * 分页查询
     * 设计原则体现：
     * 1. 开放封闭原则 - 通过PageUtil封装分页逻辑，便于扩展
     * 2. 迪米特原则 - Controller只与直接的依赖交互
     */
    @RequestMapping("/page")
    public PageUtil<DeviceEntity> page(Integer pageIndex, Integer pageSize) {
        Page<DeviceEntity> page = deviceService.page(pageIndex, pageSize);

        for (DeviceEntity deviceEntity : page.getContent()) {
            GreenhouseEntity greenhouseEntity = greenhouseService.getById(deviceEntity.getGreenhouseId());

            if (greenhouseEntity != null){
                deviceEntity.setBoxNo(greenhouseEntity.getBoxNo());
                deviceEntity.setBoxName(greenhouseEntity.getName());
            }

        }
        PageUtil<DeviceEntity> pageUtil = new PageUtil<>();
        pageUtil.setRows(page.getContent());
        pageUtil.setTotal(page.getTotalElements());

        return pageUtil;
    }

    /**
     * 土壤记录分页查询
     * 设计原则体现：
     * 1. 代码复用 - 复用分页逻辑
     * 2. 职责链模式 - 通过Service层链式处理数据
     */
    @RequestMapping("/pageSoilRecord")
    public PageUtil<DeviceSoilRecordEntity> pageSoilRecord(Integer pageIndex, Integer pageSize) {
        Page<DeviceSoilRecordEntity> page = deviceSoilRecordService.page(pageIndex, pageSize);

        for (DeviceSoilRecordEntity deviceSoilRecordEntity : page.getContent()) {
            DeviceEntity deviceEntity = deviceService.getById(deviceSoilRecordEntity.getDeviceId());

            if (deviceEntity != null){
                deviceSoilRecordEntity.setDeviceSn(deviceEntity.getSn());
                deviceSoilRecordEntity.setDeviceName(deviceEntity.getName());
                deviceSoilRecordEntity.setUnit(deviceEntity.getUnit());
            }

        }
        PageUtil<DeviceSoilRecordEntity> pageUtil = new PageUtil<>();
        pageUtil.setRows(page.getContent());
        pageUtil.setTotal(page.getTotalElements());

        return pageUtil;
    }

    @RequestMapping("/pageMonitorRecord")
    public PageUtil<DeviceMonitorRecordEntity> pageMonitorRecord(Integer pageIndex, Integer pageSize) {
        Page<DeviceMonitorRecordEntity> page = deviceMonitorRecordService.page(pageIndex, pageSize);

        for (DeviceMonitorRecordEntity deviceMonitorRecordEntity : page.getContent()) {
            DeviceEntity deviceEntity = deviceService.getById(deviceMonitorRecordEntity.getDeviceId());

            if (deviceEntity != null){
                deviceMonitorRecordEntity.setDeviceSn(deviceEntity.getSn());
                deviceMonitorRecordEntity.setDeviceName(deviceEntity.getName());
            }

        }
        PageUtil<DeviceMonitorRecordEntity> pageUtil = new PageUtil<>();
        pageUtil.setRows(page.getContent());
        pageUtil.setTotal(page.getTotalElements());
        return pageUtil;
    }
}
